package net.peelmeagrape.hibernate;

import net.peelmeagrape.hibernate.xmlgen.XmlAttribute;
import net.peelmeagrape.hibernate.xmlgen.XmlElement;
import net.peelmeagrape.hibernate.xmlgen.XmlText;

import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * The optional {@link Generator} child element names a Java class used to generate
 * unique identifiers for instances of the persistent class. {@link #value()} defines
 * the generator type.
 *<br/>
 *<br/>
 * If any parameters are required to configure or initialize the generator instance,
 * they are passed using the {@link #params()} element.
 */
@Retention(RUNTIME)
@XmlElement(name="generator")
public @interface Generator
{
    /**
     * Either a class name or one of:
     * <ul>
     * <li><b>increment</b>
     * generates identifiers of type long, short or int that are unique only when no
     * other process is inserting data into the same table. Do not use in a cluster.
     * </li>
     * <li><b>identity</b>
     * supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. The returned identifier
     * is of type long, short or int.
     * </li>
     * <li><b>sequence</b>
     * uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase. The returned identifier
     * is of type long, short or int.
     * </li>
     * <li><b>hilo</b>
     * uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a table and column
     * (by default hibernate_unique_key and next_hi respectively) as a source of hi values. The hi/lo algorithm generates identifiers that are unique only for a particular database.
     * </li>
     * <li><b>seqhilo</b>
     * uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a named database
     * sequence.
     * </li>
     * <li><b>uuid</b>
     * uses a 128-bit UUID algorithm to generate identifiers of type string, unique within a network (the IP address
     * is used). The UUID is encoded as a string of hexadecimal digits of length 32.
     * </li>
     * <li><b>guid</b>
     * uses a database-generated GUID string on MS SQL Server and MySQL.
     * </li>
     * <li><b>native</b>
     * picks identity, sequence or hilo depending upon the capabilities of the underlying database.
     * </li>
     * <li><b>assigned</b>
     * lets the application to assign an identifier to the object before save() is called. This is the default
     * strategy if no generator element is specified.
     * </li>
     * <li><b>select</b>
     * retrieves a primary key assigned by a database trigger by selecting the row by some unique key and retrieving
     * the primary key value.
     * </li>
     * <li><b>foreign</b>
     * uses the identifier of another associated object. Usually used in conjunction with a one-to-one primary key
     * association.
     * </li>
     * </ul>
     * <a href="{@docRoot}/reference/en/html/mapping.html#mapping-declaration-id-generator">Details of generator types</a>
     */
    @XmlAttribute("class") String value();

    /**
     * Optional id generator parameters. For example:
     * <pre>
        &#64;{@link Id}(
            generator = &#64;{@link Generator}(value= "seqhilo",
                params = {
                        &#64;{@link Generator.Param}(name="sequence",value="hi_value"),
                        &#64;{@link Generator.Param}(name="max_lo",value="100")
                        })
     </pre>
     */
    Param[] params() default {};

    /**
     * Parameter for an id generator ({@link Generator}).
     */
    @XmlElement(name="param")
    public @interface Param {
        @XmlAttribute String name();
        @XmlText String value();
    }
}
